package com.tzy.for10evalue.common.shardingsphere;


import com.google.common.base.Preconditions;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.Collection;
import java.util.Properties;

/**
 * 获取末尾数字，并取模算法
 */
@Getter
@Setter
public final class TZYRightNumModShardingAlgorithm implements StandardShardingAlgorithm<Comparable<?>> {

    private static final String SHARDING_COUNT_KEY = "sharding-count";

    private static final String SHARDING_RIGHT_LENGTH = "sharding-right-length";

    private Properties props = new Properties();

    private int shardingCount;

    private int rightLength;

    @Override
    public void init() {
        shardingCount = getShardingCount();
        rightLength = getShardingRightLength();
    }

    private int getShardingCount() {
        Preconditions.checkArgument(props.containsKey(SHARDING_COUNT_KEY), "Sharding count cannot be null.");
        return Integer.parseInt(props.get(SHARDING_COUNT_KEY).toString());
    }

    private int getShardingRightLength() {
        Preconditions.checkArgument(props.containsKey(SHARDING_RIGHT_LENGTH), "Sharding right length cannot be null.");
        return Integer.parseInt(props.get(SHARDING_RIGHT_LENGTH).toString());
    }

    @Override
    public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue) {

        String suffix = String.valueOf(getLastNumber(shardingValue.getValue()) % shardingCount);
        return findMatchedTargetName(availableTargetNames, suffix, shardingValue.getDataNodeInfo()).orElse(null);
    }

    @Override
    public Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue<Comparable<?>> shardingValue) {
        return availableTargetNames;
    }

    /**
     * 获取字符串最末尾的RightLength为数字
     *
     * 例如 RightLength=2
     * abcde1234sdfa324  -> 24
     * 1abc2             -> 12
     * 1aaa              -> 1
     * aaaa              -> 0
     *
     * @param shardingValue
     * @return
     */
    private Integer getLastNumber(final Comparable<?> shardingValue) {
        String str = shardingValue == null ? "" : shardingValue.toString().trim();

        if (str.length() == 0) {
            return 0;
        }

        String num = "";
        for (int i = str.length() - 1; i >= 0; i--) {
            if (str.charAt(i) >= 48 && str.charAt(i) <= 57) {
                String s = String.valueOf(str.charAt(i));
                num = s + num;
                if (num.length() == rightLength)
                    return Integer.parseInt(num);
            }
        }

        if (num.length() == 0) {
            return 0;
        } else {
            return Integer.parseInt(num);
        }
    }

    @Override
    public String getType() {
        return "TZY_RIGHT_MOD_CLASS_BASED";
    }
}